home *** CD-ROM | disk | FTP | other *** search
- // VirtualDub - Video processing and capture application
- // Copyright (C) 1998-2001 Avery Lee
- //
- // This program is free software; you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation; either version 2 of the License, or
- // (at your option) any later version.
- //
- // This program is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with this program; if not, write to the Free Software
- // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- #define f_POSITIONCONTROL_CPP
-
- #include <crtdbg.h>
- #include <math.h>
-
- #include <windows.h>
- #include <commctrl.h>
-
- #include "resource.h"
- #include "oshelper.h"
-
- #include "LevelControl.h"
-
- extern HINSTANCE g_hInst;
-
- static LRESULT APIENTRY LevelControlWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
-
- ////////////////////////////
-
- extern const char g_szLevelControlName[]="birdyLevelControl";
-
- #define MAX_TABS (8)
-
- ////////////////////////////
-
- typedef struct LevelControlData {
- int iPos[MAX_TABS];
- int iPixPos[MAX_TABS];
- COLORREF rgbTab[MAX_TABS];
- int nTabs;
- int iMovingTab;
- int iMovingOffset;
- int iTabW, iTabH;
- RECT rColorBand;
- RECT rTabBand;
- COLORREF rgbLow, rgbHigh;
- int w;
- } LevelControlData;
-
- ////////////////////////////
-
- ATOM RegisterLevelControl() {
- WNDCLASS wc;
-
- wc.style = 0;
- wc.lpfnWndProc = LevelControlWndProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = sizeof(LevelControlData *);
- wc.hInstance = g_hInst;
- wc.hIcon = NULL;
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.hbrBackground= (HBRUSH)(COLOR_3DFACE+1); //GetStockObject(LTGRAY_BRUSH);
- wc.lpszMenuName = NULL;
- wc.lpszClassName= VIDEOLEVELCONTROLCLASS;
-
- return RegisterClass(&wc);
- }
-
- static void LevelControlResize(HWND hwnd, LevelControlData *const lcd) {
- RECT r;
-
- GetClientRect(hwnd, &r);
-
- lcd->iTabH = r.bottom/2;
- lcd->iTabW = (lcd->iTabH*6+8)/16;
-
- lcd->rColorBand.left = r.left+lcd->iTabW;
- lcd->rColorBand.right = r.right-lcd->iTabW;
- lcd->rColorBand.top = r.top;
- lcd->rColorBand.bottom = r.top+lcd->iTabH-1;
-
- lcd->rTabBand.left = r.left;
- lcd->rTabBand.right = r.right;
- lcd->rTabBand.top = lcd->rColorBand.bottom;
- lcd->rTabBand.bottom = r.bottom;
-
- lcd->w = lcd->rColorBand.right - lcd->rColorBand.left;
- }
-
- static int LevelRatioToPixel(int rat, int w) {
- return (w * rat) >> 16;
- }
-
- static int LevelPixelToRatio(int pix, int w) {
- return (pix * 65535) / (w-1);
- }
-
- static LRESULT APIENTRY LevelControlWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
- LevelControlData *lcd = (LevelControlData *)GetWindowLong(hwnd, 0);
-
- switch(msg) {
-
- case WM_NCCREATE:
- if (!(lcd = new LevelControlData))
- return FALSE;
- memset(lcd,0,sizeof(LevelControlData));
-
- lcd->nTabs = 3;
- lcd->iPos[0] = 0;
- lcd->rgbTab[0] = 0xFFFFFF;
- lcd->rgbLow = 0x000000;
- lcd->rgbHigh = 0xFFFFFF;
- lcd->iMovingTab = -1;
-
- SetWindowLong(hwnd, 0, (LONG)lcd);
- return TRUE;
-
- case WM_CREATE:
- case WM_SIZE:
- LevelControlResize(hwnd, lcd);
- break;
-
- case WM_DESTROY:
- delete lcd;
- SetWindowLong(hwnd, 0, 0);
- break;
-
- case WM_PAINT:
- {
- PAINTSTRUCT ps;
- HDC hdc;
- int i, x, w, h;
- RECT r;
-
- hdc = BeginPaint(hwnd, &ps);
-
- w = lcd->w;
- h = lcd->rColorBand.bottom - lcd->rColorBand.top;
-
- if (RectVisible(hdc, &lcd->rColorBand)) {
- int dr, dg, db;
- int xlo, xhi;
- RECT rClip;
-
- dr = (signed long)(lcd->rgbHigh&0xff) - (signed long)(lcd->rgbLow&0xff);
- dg = ((signed long)(lcd->rgbHigh&0xff00) - (signed long)(lcd->rgbLow&0xff00))>>8;
- db = ((signed long)(lcd->rgbHigh&0xff0000) - (signed long)(lcd->rgbLow&0xff0000))>>16;
-
- r = lcd->rColorBand;
- xlo = 0;
- xhi = w;
-
- i = GetClipBox(hdc, &rClip);
-
- if (i!=ERROR && i!=NULLREGION) {
- RECT rClip2;
-
- IntersectRect(&rClip2, &r, &rClip);
-
- xlo = rClip2.left - r.left;
- xhi = rClip2.right - r.left;
- }
-
- for(x=xlo; x<xhi; x++) {
- HBRUSH hbr;
- COLORREF cr;
-
- r.left = lcd->rColorBand.left + x;
- r.right = r.left+1;
-
- cr = lcd->rgbLow
- + ((dr*x + w/2)/w)
- + (((dg*x + w/2)/w) << 8)
- + (((db*x + w/2)/w) << 16);
-
- if (hbr = CreateSolidBrush(cr)) {
- FillRect(hdc, &r, hbr);
- DeleteObject(hbr);
- }
- }
- }
-
- for(i=0; i<lcd->nTabs; i++) {
- POINT pt[3];
- HBRUSH hbr;
- HGDIOBJ hgoOld;
-
- pt[0].x = lcd->iPixPos[i];
- pt[1].x = lcd->iPixPos[i]+lcd->iTabW;
- pt[2].x = lcd->iPixPos[i]+2*lcd->iTabW;
- pt[0].y = pt[2].y = lcd->rColorBand.bottom+lcd->iTabH-1;
- pt[1].y = lcd->rColorBand.bottom;
-
- if (hbr = CreateSolidBrush(lcd->rgbTab[i]))
- hgoOld = SelectObject(hdc, hbr);
-
- Polygon(hdc, pt, 3);
-
- if (hbr)
- DeleteObject(SelectObject(hdc, hgoOld));
- }
-
- EndPaint(hwnd, &ps);
- }
- break;
-
- case WM_LBUTTONDOWN:
- {
- int x = LOWORD(lParam);
- int y = HIWORD(lParam);
-
- if (y >= lcd->rColorBand.bottom && y<lcd->rColorBand.bottom+lcd->iTabH) {
- int i;
- int best_tab = -1, best_dx = 100;
-
- for(i=0; i<lcd->nTabs; i++) {
- int dx = (x-lcd->iTabW) - lcd->iPixPos[i];
- int adx = abs(dx);
-
- // Pick the closest tab to cursor; if tabs are on the same
- // position, pick the lowest tab if mouse is to the left and
- // the highest tab if mouse is to the right
-
- if (adx < 8 && (best_tab == -1 || adx < best_dx ||
- (adx == best_dx && dx>0))) {
-
- best_dx = adx;
- best_tab = i;
- }
-
- }
- if (best_tab >= 0) {
- SetCapture(hwnd);
- lcd->iMovingTab = best_tab;
- lcd->iMovingOffset = x - lcd->iPixPos[best_tab];
- }
- }
- }
- break;
-
- case WM_LBUTTONUP:
- if (lcd->iMovingTab>=0) {
- ReleaseCapture();
- lcd->iMovingTab = -1;
- }
- break;
-
- case WM_MOUSEMOVE:
- if (lcd->iMovingTab>=0) {
- int pos, pixpos;
- RECT r;
-
- pixpos = (int)(signed short)LOWORD(lParam) - lcd->iMovingOffset;
- pos = LevelPixelToRatio(pixpos, lcd->w);
-
- // clip position against spectrum
-
- if (pixpos<0) {
- pos = 0;
- pixpos = 0;
- } else if (pixpos >= lcd->rColorBand.right - lcd->rColorBand.left) {
- pixpos = lcd->rColorBand.right - lcd->rColorBand.left - 1;
- pos = 0xFFFF;
- }
-
- // don't let tabs pass each other
-
- if (lcd->iMovingTab>0 && pos < lcd->iPos[lcd->iMovingTab-1]) {
- pos = lcd->iPos[lcd->iMovingTab-1];
- pixpos = lcd->iPixPos[lcd->iMovingTab-1];
- } else if (lcd->iMovingTab < lcd->nTabs-1 && pos > lcd->iPos[lcd->iMovingTab+1]) {
- pos = lcd->iPos[lcd->iMovingTab+1];
- pixpos = lcd->iPixPos[lcd->iMovingTab+1];
- }
-
- // render changes
-
- r.left = lcd->iPixPos[lcd->iMovingTab];
- r.right = lcd->iPixPos[lcd->iMovingTab]+2*lcd->iTabW+1;
- r.top = lcd->rColorBand.bottom;
- r.bottom = r.top + lcd->iTabH;
-
- InvalidateRect(hwnd, &r, TRUE);
-
- lcd->iPos[lcd->iMovingTab] = pos;
- lcd->iPixPos[lcd->iMovingTab] = pixpos;
-
- r.left = pixpos;
- r.right = pixpos+2*lcd->iTabW+1;
-
- InvalidateRect(hwnd, &r, TRUE);
-
- UpdateWindow(hwnd);
-
- // send notification message to parent window
-
- NMVLTABCHANGE nmvltc;
-
- nmvltc.hdr.code = VLCN_TABCHANGE;
- nmvltc.hdr.hwndFrom = hwnd;
- nmvltc.hdr.idFrom = GetWindowLong(hwnd, GWL_ID);
- nmvltc.iTab = lcd->iMovingTab;
- nmvltc.iNewPos = pos;
-
- SendMessage(GetParent(hwnd), WM_NOTIFY, nmvltc.hdr.idFrom, (LPARAM)&nmvltc);
- }
- break;
-
- case VLCM_SETTABCOUNT:
- lcd->nTabs = lParam;
- if (wParam)
- InvalidateRect(hwnd, &lcd->rTabBand, TRUE);
- break;
-
- case VLCM_SETTABCOLOR:
- lcd->rgbTab[LOWORD(wParam)] = lParam;
- if (HIWORD(wParam))
- InvalidateRect(hwnd, &lcd->rTabBand, TRUE);
- break;
-
- case VLCM_MOVETABPOS:
- case VLCM_SETTABPOS:
- lcd->iPos[LOWORD(wParam)] = lParam;
- lcd->iPixPos[LOWORD(wParam)] = LevelRatioToPixel(lParam, lcd->w);
- if (HIWORD(wParam))
- InvalidateRect(hwnd, &lcd->rTabBand, TRUE);
-
- if (msg == VLCM_MOVETABPOS) {
- NMVLTABCHANGE nmvltc;
-
- nmvltc.hdr.code = VLCN_TABCHANGE;
- nmvltc.hdr.hwndFrom = hwnd;
- nmvltc.hdr.idFrom = GetWindowLong(hwnd, GWL_ID);
- nmvltc.iTab = LOWORD(wParam);
- nmvltc.iNewPos = lParam;
-
- SendMessage(GetParent(hwnd), WM_NOTIFY, nmvltc.hdr.idFrom, (LPARAM)&nmvltc);
- }
- break;
-
- case VLCM_SETGRADIENT:
- lcd->rgbLow = wParam;
- lcd->rgbHigh = lParam;
- InvalidateRect(hwnd, &lcd->rColorBand, FALSE);
- break;
-
- default:
- return DefWindowProc(hwnd, msg, wParam, lParam);
- }
- return FALSE;
- }
-